package com.xxl.job.admin.controller.interceptor;

import java.util.UUID;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import com.xxl.job.admin.controller.annotation.PermessionLimit;
import com.xxl.job.admin.core.conf.LdapLogin;
import com.xxl.job.admin.core.conf.XxlJobAdminConfig;
import com.xxl.job.admin.core.util.CookieUtil;

/**
 * 权限拦截, 简易版
 *
 * @author xuxueli 2015-12-12 18:09:04
 */
@Component
public class PermissionInterceptor extends HandlerInterceptorAdapter {

    private static LdapLogin ldapLogin;

    public static final String LOGIN_IDENTITY_KEY = "XXL_JOB_LOGIN_IDENTITY";
    public static final String DEFAULT_LOGIN_IDENTITY_TOKEN;
    public static final String DEFAULT_USERNAME;
    public static final String DEFAULT_PASSWORD;

    static {
        String username = XxlJobAdminConfig.getAdminConfig().getLoginUsername();
        String password = XxlJobAdminConfig.getAdminConfig().getLoginPassword();
        DEFAULT_USERNAME = username;
        DEFAULT_PASSWORD = password;
        // login token
        String tokenTmp = DigestUtils.md5Hex(username + "_" + password);

        DEFAULT_LOGIN_IDENTITY_TOKEN = username + "_" + tokenTmp;
    }

    @Autowired
    public void setLdapLogin(LdapLogin login) {
        ldapLogin = login;
    }

    public static boolean login(HttpServletRequest request, HttpServletResponse response, String username, String password, boolean ifRemember) {

        if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {
            return false;
        }

        // 登陆,先判断配置文件的，没有再判断数据库
        String tokenTmp = DigestUtils.md5Hex(username + "_" + password);
        String finalToken = username + "_" + tokenTmp;

        if (StringUtils.isNotEmpty(DEFAULT_USERNAME)
                && StringUtils.isNotEmpty(DEFAULT_PASSWORD)
                && DEFAULT_USERNAME.equals(username)
                && DEFAULT_PASSWORD.equals(password)) {
            // 输入的是默认的用户名并且验证通过
            CookieUtil.set(response, LOGIN_IDENTITY_KEY, finalToken, ifRemember);
            return true;
        }

        boolean issuccess = ldapLogin.check(username, password);
        if (issuccess) {
            // 域成功，写cookie和session
            String token = UUID.randomUUID().toString();
            request.getSession().setAttribute(LOGIN_IDENTITY_KEY, token);
            CookieUtil.set(response, LOGIN_IDENTITY_KEY, token, ifRemember);
            return true;
        }

        // 登陆失败
        return false;
    }

    public static void logout(HttpServletRequest request, HttpServletResponse response) {
        request.getSession().removeAttribute(LOGIN_IDENTITY_KEY);
        CookieUtil.remove(request, response, LOGIN_IDENTITY_KEY);
    }

    public static boolean ifLogin(HttpServletRequest request) {
        // 登陆判断
        String indentityInfo = CookieUtil.getValue(request, LOGIN_IDENTITY_KEY);
        if (StringUtils.isEmpty(indentityInfo)) {
            return false;
        }

        // 配置文件的
        if (DEFAULT_LOGIN_IDENTITY_TOKEN.equals(indentityInfo)) {
            return true;
        }
        // 域登陆的判断一下session里面的
        Object obj = request.getSession().getAttribute(LOGIN_IDENTITY_KEY);
        if (obj != null) {
            String token = obj.toString();
            if (indentityInfo.equals(token)) {
                return true;
            }
        }

        return false;
    }


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        if (!(handler instanceof HandlerMethod)) {
            return super.preHandle(request, response, handler);
        }

        if (!ifLogin(request)) {
            HandlerMethod method = (HandlerMethod) handler;
            PermessionLimit permission = method.getMethodAnnotation(PermessionLimit.class);
            if (permission == null || permission.limit()) {
                response.sendRedirect(request.getContextPath() + "/toLogin");
                //request.getRequestDispatcher("/toLogin").forward(request, response);
                return false;
            }
        }

        return super.preHandle(request, response, handler);
    }

}
